package com.link2room.rodimus.facade.impl;

import com.link2room.common.entity.BaseEntity;
import com.link2room.common.jpa.condition.ConditionDetail;
import com.link2room.common.jpa.condition.L2RCondition;
import com.link2room.common.jpa.criteria.CriteriaUtil;
import com.link2room.common.jpa.result.QueryResult;
import com.link2room.common.service.ICommonService;
import com.link2room.common.util.ClassConverUtil;
import com.link2room.common.util.StringUtil;
import com.link2room.enums.exception.RodimusSysExceptionEnum;
import com.link2room.rodimus.dto.param.base.ExpressBaseDto;
import com.link2room.rodimus.dto.param.base.InvoiceBaseParamDto;
import com.link2room.rodimus.dto.param.inside.ExpressFindInsideParamDto;
import com.link2room.rodimus.dto.param.inside.ExpressNewInsideParamDto;
import com.link2room.rodimus.dto.result.base.InvoiceDetailDto;
import com.link2room.rodimus.dto.result.base.InvoiceDto;
import com.link2room.rodimus.entity.InvoiceDetail;
import com.link2room.rodimus.entity.MemberInvoice;
import com.link2room.rodimus.exception.RodimusException;
import com.link2room.rodimus.facade.IInvoiceFacadeService;
import com.link2room.rodimus.feign.rodimus.ExpressFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by sss on 2017/8/29.
 */
@Component("invoiceFacadeService")
public class InvoiceFacadeServiceImpl implements IInvoiceFacadeService {
    @Resource
    private ICommonService commonService;
    @Autowired
    private ExpressFeignService expressFeignService;

    static ReentrantLock reentrantLock=new ReentrantLock();

    @Override
    public void saveInvoiceDetail(InvoiceBaseParamDto invoiceBaseParamDto)throws Exception{
        InvoiceDetailDto invoiceDetailDto=invoiceBaseParamDto.getInvoiceDetailDto();
        invoiceDetailDto.setInvoiceNo(this.getNo("INVOICE_NO"));
        if(invoiceDetailDto.getPostType().equals(1)){
            ExpressNewInsideParamDto expressNewInsideParamDto=new ExpressNewInsideParamDto();
            expressNewInsideParamDto.setLhotelCode(invoiceDetailDto.getLhotelCode());
            expressNewInsideParamDto.setAddress(invoiceDetailDto.getReceiverAddress());
            expressNewInsideParamDto.setReceiverName(invoiceDetailDto.getReceiverName());
            expressNewInsideParamDto.setMemberNo(invoiceDetailDto.getMemberNo());
            expressNewInsideParamDto.setMobile(invoiceDetailDto.getReceiverMobile());
            expressNewInsideParamDto.setRemark(invoiceDetailDto.getComment());
            expressNewInsideParamDto.setSourceNo(invoiceDetailDto.getInvoiceNo());
            //TODO 临时写死类型
            expressNewInsideParamDto.setSourceType("INVOICE");
            expressNewInsideParamDto.setGoodName(invoiceDetailDto.getOrderName());
            ExpressBaseDto expressBaseDto = expressFeignService.newExpress(expressNewInsideParamDto).getResultInfo();
            invoiceDetailDto.setExpressNo(expressBaseDto.getExpressNo());
        }
        if(invoiceBaseParamDto.getInvoiceDetailDto()!=null){
            commonService.save(ClassConverUtil.copyProperties(invoiceDetailDto, InvoiceDetail.class));
        }
        this.saveOrUpdateMemberInvoice(invoiceBaseParamDto.getInvoiceDetailDto());
    }

    @Override
    public void updateInvoiceDetail(InvoiceBaseParamDto invoiceBaseParamDto)throws Exception{
        InvoiceDetailDto invoiceDetailDto=invoiceBaseParamDto.getInvoiceDetailDto();
        InvoiceDetail queryInvoiceDetail=new InvoiceDetail();
        queryInvoiceDetail.setLhotelGroupCode(invoiceDetailDto.getLhotelGroupCode());
        queryInvoiceDetail.setInvoiceNo(invoiceDetailDto.getInvoiceNo());
        InvoiceDetail invoiceDetail=commonService.findOneEQ(InvoiceDetail.class,queryInvoiceDetail);
        if(invoiceDetail!=null){
            if(invoiceDetailDto.getStatus()!=null){
                invoiceDetail.setStatus(invoiceDetailDto.getStatus());
            }
            commonService.merge(invoiceDetail);
        }
    }

    @Override
    public QueryResult<InvoiceDetailDto>findInvoiceDetailList(InvoiceBaseParamDto invoiceBaseParamDto)throws Exception{
        L2RCondition l2RCondition=new L2RCondition();
        l2RCondition.setAndConditions(new ConditionDetail[]{
                new ConditionDetail(BaseEntity.BaseEntity_.lhotelGroupCode.toString(), CriteriaUtil.Operator.EQ,invoiceBaseParamDto.getLhotelGroupCode()),
                new ConditionDetail(BaseEntity.BaseEntity_.lhotelCode.toString(), CriteriaUtil.Operator.EQ,invoiceBaseParamDto.getLhotelCode()),
                new ConditionDetail(InvoiceDetail.InvoiceDetail_.invoiceNo.toString(), CriteriaUtil.Operator.EQ,invoiceBaseParamDto.getInvoiceNo()),
                new ConditionDetail(InvoiceDetail.InvoiceDetail_.orderNo.toString(), CriteriaUtil.Operator.EQ,invoiceBaseParamDto.getOrderNo()),
                new ConditionDetail(InvoiceDetail.InvoiceDetail_.invoiceTitle.toString(), CriteriaUtil.Operator.LIKE,"%"+invoiceBaseParamDto.getInvoiceTitle()+"%"),
                new ConditionDetail(InvoiceDetail.InvoiceDetail_.taxpayerId.toString(), CriteriaUtil.Operator.EQ,invoiceBaseParamDto.getTaxpayerId()),
                new ConditionDetail(InvoiceDetail.InvoiceDetail_.terminalNo.toString(), CriteriaUtil.Operator.EQ,invoiceBaseParamDto.getTerminalNo())
        });
        QueryResult<InvoiceDetail> invoiceDetailQueryResult = commonService.findAllByCondition(InvoiceDetail.class, l2RCondition,invoiceBaseParamDto.getCurrentPage(),invoiceBaseParamDto.getPageSize());
        return ClassConverUtil.copyQueryResultToDtoQueryResult(invoiceDetailQueryResult,InvoiceDetailDto.class,false);
    }

    @Override
    public InvoiceDto findInvoiceDetail(InvoiceBaseParamDto invoiceBaseParamDto)throws Exception{
        InvoiceDetail invoiceDetail;
        if(invoiceBaseParamDto.getId()!=null){
            invoiceDetail=commonService.findOneById(InvoiceDetail.class,invoiceBaseParamDto.getId());
        }else {
            InvoiceDetail queryInvoiceDetail=new InvoiceDetail();
            queryInvoiceDetail.setLhotelGroupCode(invoiceBaseParamDto.getLhotelGroupCode());
            queryInvoiceDetail.setInvoiceNo(invoiceBaseParamDto.getInvoiceNo());
            invoiceDetail=commonService.findOneEQ(InvoiceDetail.class,queryInvoiceDetail);
        }
        InvoiceDto invoiceDto=new InvoiceDto();
        invoiceDto.setInvoiceDetailDto(ClassConverUtil.copyPropertiesToDto(invoiceDetail,InvoiceDetailDto.class,false));
        if(invoiceDetail!=null&&invoiceDetail.getPostType().equals(1)&&StringUtil.isNotBlank(invoiceDetail.getExpressNo())){
            if(StringUtil.isNotBlank(invoiceDetail.getExpressNo())){
                ExpressFindInsideParamDto expressFindInsideParamDto=new ExpressFindInsideParamDto();
                expressFindInsideParamDto.setLhotelGroupCode(invoiceDetail.getLhotelGroupCode());
                expressFindInsideParamDto.setExpressNo(invoiceDetail.getExpressNo());
                QueryResult<ExpressBaseDto> expressBaseDtoQueryResult = expressFeignService.findExpress(expressFindInsideParamDto.paramToMap()).getQueryResult();
                if(expressBaseDtoQueryResult.getResultlist()!=null&&expressBaseDtoQueryResult.getResultlist().size()>0){
                    invoiceDto.setExpressBaseDto(expressBaseDtoQueryResult.getResultlist().get(0));
                }
            }
        }
        return invoiceDto;
    }

    private void saveOrUpdateMemberInvoice(InvoiceDetailDto invoiceDetailDto) throws Exception {
        if(StringUtil.isNotBlank(invoiceDetailDto.getMemberNo())){
            MemberInvoice queryMemberInvoice=new MemberInvoice();
            queryMemberInvoice.setLhotelGroupCode(invoiceDetailDto.getLhotelGroupCode());
            queryMemberInvoice.setMemberNo(invoiceDetailDto.getMemberNo());
            if(invoiceDetailDto.getInvoiceTitleType().equals(1)){
                queryMemberInvoice.setInvoiceTitle(invoiceDetailDto.getInvoiceTitle());
            }else if(invoiceDetailDto.getInvoiceTitleType().equals(2)){
                queryMemberInvoice.setTaxpayerId(invoiceDetailDto.getTaxpayerId());
            }else {
                throw new RodimusException(RodimusSysExceptionEnum.INVOICE_TITLE_TYPE_MISS);
            }
            MemberInvoice memberInvoice=commonService.findOneEQ(MemberInvoice.class,queryMemberInvoice);
            if(memberInvoice==null){
                commonService.save(ClassConverUtil.copyProperties(invoiceDetailDto,MemberInvoice.class));
            }
        }
    }

    private String getNo(String noType)throws Exception{
        try {
            reentrantLock.lock();
            List params=new ArrayList<>();
            params.add(noType);
            String no=commonService.findOneFieldByProcedure("create_No",params);
            return no;
        }finally {
            reentrantLock.unlock();
        }
    }
}
